package com.cyanite.playlv2;

import com.cyanite.playlv2.interpolator.EasingType.Type;
import com.cyanite.playlv2.interpolator.ExpoInterpolator;
import com.cyanite.playlv2.util.NotificationsUtil;
import com.cyanite.playlv2.widget.Panel;
import com.cyanite.playlv2.widget.Panel.OnPanelListener;
import com.cyanite.playlv2.widget.ShareListAdapter;
import com.cyanite.playlv2api.types.Group;
import com.cyanite.playlv2api.types.Info;
import com.cyanite.playlv2api.types.Response;
import com.cyanite.playlv2api.types.Task;
import com.cyanite.playlv2api.types.TaskCategory;
import com.cyanite.playlv2api.util.ConstantsUtils;
import com.cyanite.playlv2api.util.ConstantsUtils.ShareListAdapterConsts;
import com.cyanite.playlv2api.util.ConstantsUtils.ShareSecretLevelConsts;
import com.cyanite.playlv2api.util.ConstantsUtils.TaskCategoryConsts;

import android.app.Activity;
import android.app.ProgressDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.Bitmap;
import android.location.Location;
import android.os.AsyncTask;
import android.os.Bundle;
import android.provider.MediaStore;
import android.text.TextUtils;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.Spinner;
import android.widget.TextView;
import android.widget.Toast;

public class ShareTrafficActivity extends Activity {

    public static final String EXTRA_USER_ID = PlayLv2.PACKAGE_NAME
            + ".ShareTrafficActivity.EXTRA_USER_ID";
    public static final String EXTRA_TASK_CATEGORY_PARCEL = PlayLv2.PACKAGE_NAME
            + ".ShareTrafficActivity.EXTRA_TASK_CATEGORY_PARCEL";

    private StateHolder mStateHolder;
    private ProgressDialog mProgressDialog;
    private View mViewProgressBar;
    private Spinner mInfo1;
    private EditText mInfo2;
    private EditText mInfo3;
    private EditText mInfo4;
    private LinearLayout mllSecond;
    private LinearLayout mEmpty;
    private ListView mListView;
    private Panel mPanel;
    private ImageView mPhoto;

    private BroadcastReceiver mLoggedOutReceiver = new BroadcastReceiver() {
        @Override
        public void onReceive(Context context, Intent intent) {
            finish();
        }
    };

    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.share_traffic_activity);
        registerReceiver(mLoggedOutReceiver, new IntentFilter(PlayLv2.INTENT_ACTION_LOGGED_OUT));
        this.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

        mStateHolder = new StateHolder();
        if (getIntent().hasExtra(EXTRA_USER_ID)) {
            mStateHolder.setUserId(getIntent().getExtras().getString(EXTRA_USER_ID));
        }

        if (getIntent().hasExtra(EXTRA_TASK_CATEGORY_PARCEL)) {
            mStateHolder.setTaskCategory((TaskCategory) getIntent().getExtras().getParcelable(
                    EXTRA_TASK_CATEGORY_PARCEL));
        }
        mStateHolder.startTaskShareHistory(this);

        mStateHolder.setIsLoggedInUser(mStateHolder.getUserId() == null
                || mStateHolder.getUserId().equals(((PlayLv2) getApplication()).getUserId()));

        mViewProgressBar = findViewById(R.id.shareTrafficProgress);
        mViewProgressBar.setVisibility(View.VISIBLE);
        ensureUi();
    }

    private void ensureUi() {
        mInfo1 = (Spinner) findViewById(R.id.spTrafficTools);
        mInfo2 = (EditText) findViewById(R.id.etFrom);
        mInfo3 = (EditText) findViewById(R.id.etTo);
        mInfo4 = (EditText) findViewById(R.id.etTrafficShout);
        mListView = (ListView) findViewById(R.id.lvTrafficList);
        mEmpty = (LinearLayout) findViewById(R.id.llEmptyTraffic);

        this.setTitle(R.string.trip_traffic_tool_information);
        String plane = this.getString(R.string.trip_share_traffic_plane);
        String train = this.getString(R.string.trip_share_traffic_train);
        String car = this.getString(R.string.trip_share_traffic_car);
        String ship = this.getString(R.string.trip_share_traffic_ship);
        String bus = this.getString(R.string.trip_share_traffic_bus);
        String subway = this.getString(R.string.trip_share_traffic_subway);
        String bike = this.getString(R.string.trip_share_traffic_bike);
        String walk = this.getString(R.string.trip_share_traffic_walk);
        String taxi = this.getString(R.string.trip_share_traffic_taxi);

        final String[] themes = {
                plane, train, car, ship, bus, subway, bike, walk, taxi
        };
        ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
                android.R.layout.simple_spinner_item, themes);

        adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
        mInfo1.setAdapter(adapter);

        TextView taskDescription = (TextView) findViewById(R.id.tvTrafficDescription);
        taskDescription.setText(R.string.trip_share_traffic);

        mllSecond = (LinearLayout) findViewById(R.id.llSecondlayer);
        mllSecond.getBackground().setAlpha(0);
        mllSecond.setOnClickListener(new View.OnClickListener(){
            public void onClick(View v) {
                if (mStateHolder.getIsPanelOpen()) {
                    mPanel.setOpen(false, true);
                }
            }

        });
        mInfo2.setHint(R.string.share_traffic_from);
        mInfo3.setHint(R.string.share_traffic_to);
        mInfo4.setHint(R.string.trip_share_near_advance);

        mPhoto = (ImageView)findViewById(R.id.ivTrafficPhoto);
        ImageView btnCamera = (ImageView)findViewById(R.id.btnTrafficCamera);
        btnCamera.setOnClickListener(new View.OnClickListener()  {
            public void onClick(View v)  {
                showProgressDialog(R.string.camera_initializing);
                Intent cameraIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
                startActivityForResult(cameraIntent, 0);
            }
        });

        Button btnCreate = (Button) findViewById(R.id.btnPublisgTraffic);
        btnCreate.setOnClickListener(new OnClickListener() {
            public void onClick(View arg0) {
                String info1 = mInfo1.getSelectedItem().toString();
                String info2 = mInfo2.getText().toString();
                String info3 = mInfo3.getText().toString();
                String info4 = mInfo4.getText().toString();

                if (!TextUtils.isEmpty(info2)
                        && !TextUtils.isEmpty(info3)) {
                    Info info = new Info();
                    info.setInfo1(info1);
                    info.setInfo2(info2);
                    info.setInfo3(info3);
                    info.setInfo4(info4);
                    mStateHolder.startTaskShareTraffic(ShareTrafficActivity.this,
                            info, ShareSecretLevelConsts.SHARE_SECRET_LEVEL_OPEN);
                }   else {
                    Toast.makeText(ShareTrafficActivity.this,
                            getResources().getString(R.string.share_info_content_null),
                            Toast.LENGTH_LONG).show();
                }
            }
        });

        switch (mStateHolder.getTaskCategory().getType()) {
            case TaskCategoryConsts.TASK_CATEGORY_TYPE_DISCOUNT:
                taskDescription.setText(R.string.trip_share_discount);
                this.setTitle(R.string.trip_share_task_discount_note);
                mInfo2.setHint(R.string.trip_share_price_address);
                mInfo3.setHint(R.string.trip_share_discount_time);
                mInfo4.setHint(R.string.trip_share_discount_detail);
                break;
            default:
                break;
        }
        mPanel = (Panel) findViewById(R.id.bottomPanel);
        mPanel.setInterpolator(new ExpoInterpolator(Type.OUT));
        mPanel.setOnPanelListener(new OnPanelListener() {
            public void onPanelClosed(Panel panel) {
                mllSecond.setVisibility(View.GONE);
                mllSecond.getBackground().setAlpha(0);
                mStateHolder.setIsPanelOpen(false);
            }

            public void onPanelOpened(Panel panel) {
                mllSecond.setVisibility(View.VISIBLE);
                mllSecond.getBackground().setAlpha(170);
                mStateHolder.setIsPanelOpen(true);
            }
        });

        if (mStateHolder.getIsLoggedInUser()) {
            mPanel.setVisibility(View.VISIBLE);
        } else {
            mPanel.setVisibility(View.GONE);
        }

        updateUi();
    }

    private void updateUi() {
        if (mStateHolder.getTasks() != null) {
            ShareListAdapter mListAdapter = new ShareListAdapter(this,
                    ShareListAdapterConsts.SHARE_LIST_ADAPTER_TRAFFIC, mInfo2.getHint(),
                    mInfo3.getHint(), "");
            mListAdapter.setGroup(mStateHolder.getTasks());
            mListView.setAdapter(mListAdapter);
            mListView.setOnItemClickListener(new OnItemClickListener() {
                public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
                    Task task = (Task) parent.getAdapter().getItem(position);
                    Intent intent = new Intent(ShareTrafficActivity.this, AddTipsActivity.class);
                    intent.putExtra(AddTipsActivity.EXTRA_TASK_PARCEL, task);
                    startActivity(intent);
                }
            });

            TextView tvprompt = (TextView)findViewById(R.id.ivTrafficprompt);
            String string = getString(R.string.share_activity_title_note)+mStateHolder.getTasks().get(mStateHolder.getTasks().size()-1).getPostDate();
            tvprompt.setText(string);
        }
    }

    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);
        dismissProgressDialog();
        if (data.getAction() == null && resultCode == 0 ){
            finish();
        }else{
            Bundle extras = data.getExtras();
            Bitmap bmp = (Bitmap) extras.get("data");
            mPhoto.setImageBitmap(bmp);
            mPhoto.setVisibility(View.VISIBLE);
            TaskSetPhoto mTaskSetPhoto = new TaskSetPhoto(this, bmp);
            mTaskSetPhoto.execute();
        }
    }

    @Override
    public boolean onKeyDown(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK) {
            if (mStateHolder.getIsPanelOpen()) {
                mPanel.setOpen(false, true);
            } else {
                finish();
            }
            return true;
        } else
            return super.onKeyDown(keyCode, event);
    }

    @Override
    public void onPause() {
        super.onPause();
        if (isFinishing()) {
            mStateHolder.cancelTasks();
        }
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        mStateHolder.cancelTasks();
        unregisterReceiver(mLoggedOutReceiver);
    }

    private void onHistoryTaskComplete(Group<Task> tasks, Exception ex) {
        mViewProgressBar.setVisibility(View.GONE);
        if (tasks != null && tasks.size() > 0) {
            mEmpty.setVisibility(View.GONE);
            mStateHolder.setTasks(tasks);
            updateUi();
        } else {
            mEmpty.setVisibility(View.VISIBLE);
        }
    }

    private static class ShareHistoryTask extends AsyncTask<Void, Void, Group<Task>> {

        private ShareTrafficActivity mActivity;
        private String mTaskCategoryId;
        private String mViewUserId;
        private Exception mReason;

        public ShareHistoryTask(ShareTrafficActivity activity, String viewUserId, String taskcatId) {
            mActivity = activity;
            mTaskCategoryId = taskcatId;
            mViewUserId = viewUserId;
        }

        @Override
        protected void onPreExecute() {
        }

        @Override
        protected Group<Task> doInBackground(Void... params) {
            try {
                return ((PlayLv2) mActivity.getApplication()).getPlayLv2Api().tasks(mViewUserId,
                        mTaskCategoryId);
            } catch (Exception ex) {
                mReason = ex;
                return null;
            }
        }

        @Override
        protected void onPostExecute(Group<Task> tasks) {
            if (mActivity != null) {
                mActivity.onHistoryTaskComplete(tasks, mReason);
            }
        }
    }

    private void onShareTrafficTaskComplete(Response response, Exception ex) {
        dismissProgressDialog();

        if (response != null && response.getValue().equals("0")) {
            mInfo2.setText("");
            mInfo3.setText("");
            mInfo4.setText("");
            Toast.makeText(this, getResources().getString(R.string.share_info_ok),
                    Toast.LENGTH_LONG).show();
            if (mStateHolder.getIsPanelOpen()) {
                mPanel.setOpen(false, true);
            }
            mStateHolder.startTaskShareHistory(this);
        } else {
            NotificationsUtil.ToastReasonForFailure(this, ex);
        }
    }

    private static class ShareTrafficTask extends AsyncTask<Void, Void, Response> {

        private ShareTrafficActivity mActivity;
        private Exception mReason;
        private Task mTask;

        public ShareTrafficTask(ShareTrafficActivity activity, Task task) {
            mActivity = activity;
            mTask = task;
        }

        @Override
        protected void onPreExecute() {
            mActivity.showProgressDialog(R.string.share_info_progress_note);
        }

        @Override
        protected Response doInBackground(Void... params) {
            String validateGps = "1";
            Location loc = ((PlayLv2) mActivity.getApplication()).getLastKnownLocation();
            if (loc == null) {
                try {
                    Thread.sleep(ConstantsUtils.SLEEP_TIME_IF_NO_LOCATION);
                } catch (InterruptedException ex) {
                }
                loc = ((PlayLv2) mActivity.getApplication()).getLastKnownLocation();
            }
            if (loc != null) {
                mTask.setLatitude(String.valueOf(loc.getLatitude()));
                mTask.setLongitude(String.valueOf(loc.getLongitude()));
            }   else {
                validateGps = "2";
            }
            try {
                Response response = null;
                response = ((PlayLv2) mActivity.getApplication()).getPlayLv2Api().share(mTask, validateGps);
                if (response == null) response = new Response();
                return response;
            } catch (Exception ex) {
                mReason = ex;
                return null;
            }
        }

        @Override
        protected void onPostExecute(Response response) {
            if (mActivity != null) {
                mActivity.onShareTrafficTaskComplete(response, mReason);
            }
        }

        public void setActivity(ShareTrafficActivity activity) {
            mActivity = activity;
        }

        @Override
        protected void onCancelled() {
            mActivity.dismissProgressDialog();
        }
    }

    private void onTaskSetPhotoComplete(Response response, Exception ex) {
        dismissProgressDialog();
        if (response != null) {
            mStateHolder.setPhotoId(response.getValue());
        } else {
            NotificationsUtil.ToastReasonForFailure(this, ex);
        }
    }

    private static class TaskSetPhoto extends AsyncTask<Void, Void, Response> {

        private ShareTrafficActivity mActivity;
        private Exception mReason;
        private Bitmap mBmp;

        public TaskSetPhoto(ShareTrafficActivity activity, Bitmap bmp) {
            mActivity = activity;
            mBmp = bmp;
        }

        @Override
        protected void onPreExecute() {
            mActivity.showProgressDialog(R.string.share_info_bitmap_progress_note);
        }

        @Override
        protected Response doInBackground(Void... params) {
            try {
                return ((PlayLv2) mActivity.getApplication()).getPlayLv2Api().photoUpdate2(mBmp);
            } catch (Exception ex) {
                mReason = ex;
                return null;
            }
        }

        @Override
        protected void onPostExecute(Response response) {
            if (mActivity != null) {
                mActivity.onTaskSetPhotoComplete(response, mReason);
            }
        }

        @Override
        protected void onCancelled() {
            mActivity.dismissProgressDialog();
        }
    }

    private ProgressDialog showProgressDialog(int res) {
        if (mProgressDialog == null) {
            ProgressDialog dialog = new ProgressDialog(this);
            dialog.setIndeterminate(true);
            dialog.setCancelable(true);
            mProgressDialog = dialog;
        }
        mProgressDialog.setMessage(getString(res));
        mProgressDialog.show();
        return mProgressDialog;
    }

    private void dismissProgressDialog() {
        try {
            mProgressDialog.dismiss();
        } catch (IllegalArgumentException e) {
            // We don't mind. android cleared it for us.
        }
    }

    private static class StateHolder {

        private String mUserId;
        private boolean mIsLoggedInUser;
        private TaskCategory mTaskCategory;
        private ShareHistoryTask mTaskShareHistory;
        private ShareTrafficTask mTaskShareTraffic;
        private Group<Task> mTasks;
        private boolean mIsPanelOpen;
        private String mPhotoId;

        public StateHolder() {
            mIsLoggedInUser = false;
            mIsPanelOpen = false;
            mPhotoId = "";
        }

        public boolean getIsLoggedInUser() {
            return mIsLoggedInUser;
        }

        public void setIsLoggedInUser(boolean isLoggedInUser) {
            mIsLoggedInUser = isLoggedInUser;
        }

        public boolean getIsPanelOpen() {
            return mIsPanelOpen;
        }

        public void setIsPanelOpen(boolean isOpen) {
            mIsPanelOpen = isOpen;
        }

        public void setPhotoId(String id)   {
            mPhotoId = id;
        }

        public String getUserId() {
            return mUserId;
        }

        public void setUserId(String userId) {
            mUserId = userId;
        }

        public TaskCategory getTaskCategory() {
            return mTaskCategory;
        }

        public void setTaskCategory(TaskCategory taskcat) {
            mTaskCategory = taskcat;
        }

        public Group<Task> getTasks() {
            return mTasks;
        }

        public void setTasks(Group<Task> tasks) {
            mTasks = tasks;
        }

        public void startTaskShareHistory(ShareTrafficActivity activity) {
            mTaskShareHistory = new ShareHistoryTask(activity, mUserId, mTaskCategory.getId());
            mTaskShareHistory.execute();
        }

        public void startTaskShareTraffic(ShareTrafficActivity activity, Info info, int secretLevel) {
            Task task = new Task();
            task.setInfo(info);
            task.setPhotoId(mPhotoId);
            task.setSecretLevel(secretLevel);
            task.setTaskCategoryId(mTaskCategory.getId());
            mTaskShareTraffic = new ShareTrafficTask(activity, task);
            mTaskShareTraffic.execute();
        }

        public void cancelTasks() {
            if (mTaskShareTraffic != null) {
                mTaskShareTraffic.setActivity(null);
                mTaskShareTraffic.cancel(true);
            }
        }
    }
}
